#include <algorithm/analytical_model/algorithm/cpu/VectorConvert.h>
#include <algorithm/analytical_model/algorithm/cuda/inter_op/receiver/CylinderReceiver.h>
#include <algorithm/analytical_model/algorithm/cuda/inter_op/utils/convert/receiver/ConvertReceiver.h>
#include <algorithm/analytical_model/algorithm/geometry/Cylinder3D.h>
#include <algorithm/shared/data/scene/Receiver.h>
#include <algorithm/shared/data/topology/geometry/Cylinder3D.h>

// #include <iostream>
// #include <utils/Format.h>
#include <utils/ParaUtils.h>


template <>
void solar::cuda::inter_op::convertReceiver(CylinderReceiver* input_ptr,
                                            solar::Receiver* output_ptr)
{
    auto input = *input_ptr;
    auto output = *output_ptr;
    const auto center = input.getPosition();
    const auto input_size = input.getSize();
    const auto geometry_receiver = SOLAR_GET_VALUE2(solar, Receiver, geometry_, output);
    auto* cylinder3d_geometry = dynamic_cast<Cylinder3D*>(geometry_receiver.get());
    SOLAR_SET_VALUE(Cylinder3D, height_, input_size.y, *cylinder3d_geometry)
    SOLAR_SET_VALUE(Cylinder3D, radius_, input_size.x, *cylinder3d_geometry)
    SOLAR_SET_VALUE(Cylinder3D, center_, cpu::toVec3(center), *cylinder3d_geometry)
}

template <>
void solar::cuda::inter_op::convertReceiver(solar::Receiver* input_ptr,
                                            CylinderReceiver* output_ptr)
{
    const auto geometry_receiver = SOLAR_GET_VALUE2(solar, Receiver, geometry_, *input_ptr);
    auto* cylinder3d_geometry = dynamic_cast<Cylinder3D*>(geometry_receiver.get());
    const auto center = SOLAR_GET_VALUE(Cylinder3D, center_, *cylinder3d_geometry);
    const auto height = SOLAR_GET_VALUE(Cylinder3D, height_, *cylinder3d_geometry);
    const auto radius = SOLAR_GET_VALUE(Cylinder3D, radius_, *cylinder3d_geometry);
    // std::cout << center.toString() << '\n';
    // std::cout << height << '\n';
    // std::cout << radius << '\n';
    output_ptr->setSize({static_cast<float>(radius), static_cast<float>(height), 0});
    output_ptr->setPosition(cpu::toFloat3(center));
}
